﻿using Mengsk.ProxyDelivery.Domain;
using Mengsk.ProxyDelivery.HTTPHelpers;
using Mengsk.ProxyDelivery.Service;
using Mengsk.ProxyDelivery.Utls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace Mengsk.ProxyDelivery.Print.Domain.DeliveryNumberGenerator
{
    class YuanTongDeliveryNumberGenerator : DeliveryNumberGenerator
    {
        /// <summary>
        /// 订单处理地址，获取，与取消，都采用这个地址 测试模式
        /// </summary>
        const string YTOORDERURL_DEBUG = "http://58.32.246.71:8088/CommonOrderModeBServlet.action";
        /// <summary>
        /// 订单处理地址，获取，与取消，都采用这个地址 正式模式
        /// </summary>
        const string YTOORDERURL = "http://218.83.245.210:9001/web/CommonOrderModeBServlet.action";

        /// <summary>
        /// 目地地网点信息获取，超区检查,测试模式地址
        /// </summary>
        const string YTOADDRESSURL_DEBUG = "http://58.32.246.70:8001/BaseDataManagent";

        /// <summary>
        /// 目地地网点信息获取，超区检查,测试模式地址
        /// </summary>
        const string YTOADDRESSURL = "http://58.32.246.70:8088/BaseDataManagent/";

        private string clientId = null;

        private string key = null;

        public string GetClientId()
        {
            if (string.IsNullOrWhiteSpace(clientId))
            {
                clientId = LocalConfigService.GetValue("YTOClientId", "");
            }
            if (string.IsNullOrWhiteSpace(clientId))
            {
                throw new Exception("圆通商户账号ID为空，必须配置");
            }
            return clientId;
        }

        public string GetClientKey()
        {
            if (string.IsNullOrWhiteSpace(key))
            {
                key = LocalConfigService.GetValue("YTOClientPass", "");
            }
            if (string.IsNullOrWhiteSpace(key))
            {
                throw new Exception("圆通商户账号密码为空，必须配置");
            }
            return key;
        }

        public override bool AcceptDeliveryCompany(string arg)
        {
            return arg.Contains("圆通");
        }

        public override string GenenrateNext(string deliveryNumberAlgorithm, string current)
        {
            if (string.IsNullOrWhiteSpace(current) || (current.Length != 10 && current.Length != 12 && current.Length != 16))
            {
                throw new Exception("圆通快递单号必须为10,12,16位:" + current);
            }
            int numberStartIndex = current.IndexOfAny("0123456789".ToArray());
            string prefix = numberStartIndex > 0 ? current.Substring(0, numberStartIndex) : "";
            long currentNumber = long.Parse(current.Substring(numberStartIndex));
            long nextNumber = currentNumber + 1;
            string newNumber = prefix + nextNumber.ToString("D" + (current.Length - prefix.Length));
            return newNumber;
        }

        private XDocument Post(string url, string content)
        {
            string allc = content + GetClientKey();
            var md5 = MD5Util.Md5Bytes(allc);
            var ser = System.Convert.ToBase64String(md5);

            Dictionary<string, string> param = new Dictionary<string, string>();
            param["logistics_interface"] = content;
            param["clientId"] = clientId;
            param["data_digest"] = ser;
            var ret = MSHttpRestful.DoWithRetry<string>(() => MSHttpRestful.PostUrlEncodeBodyReturnString(url, param));
            if (string.IsNullOrWhiteSpace(ret))
            {
                throw new Exception("圆通系统没有返回任何数据");
            }

            try
            {
                return XDocument.Parse(ret);
            }
            catch (Exception ex)
            {
                throw new Exception("解析圆通数据失败:" + ex.Message, ex);
            }
        }

        public override string GenenrateOnline(Order order, string wuliuId)
        {
            var orderGoods = order.OrderGoodss.Where(obj => (int)obj.State <= (int)OrderState.Shipped).ToArray();
            XElement root = new XElement("RequestOrder");
            bool isDebug = LocalConfigService.GetValue("YTODebug", "false") == "false" ? false : true;
            root.Add(new XElement("clientID", GetClientId()));
            root.Add(new XElement("logisticProviderID", "YTO"));
            root.Add(new XElement("customerId", clientId));
            root.Add(new XElement("txLogisticID", wuliuId));
            root.Add(new XElement("orderType", order.PopPayType == OrderPopPayType.COD ? "0" : "1"));
            root.Add(new XElement("serviceType", "1"));
            root.Add(new XElement("totalServiceFee", "0.0"));
            //root.Add(new XElement("codSplitFee", "0.0"));
            root.Add(new XElement("goodsValue", orderGoods.Select(obj => (obj.PopPrice > obj.Price ? obj.PopPrice : obj.Price) * obj.Count).Sum().ToString("F1")));
            root.Add(new XElement("special", "0"));
            root.Add(new XElement("type", "0"));

            XElement sender = new XElement("sender");
            sender.Add(new XElement("name", "胡平"));
            sender.Add(new XElement("postCode", "610100"));
            sender.Add(new XElement("phone", "028-88456638"));

            sender.Add(new XElement("prov", "四川"));
            sender.Add(new XElement("city", "成都市,龙泉驿区"));
            sender.Add(new XElement("address", "阳光大道24号"));
            root.Add(sender);

            XElement receiver = new XElement("receiver");
            receiver.Add(new XElement("name", order.ReceiverName));
            if (string.IsNullOrWhiteSpace(order.ReceiverPhone) == false)
                receiver.Add(new XElement("phone", order.ReceiverPhone));
            if (string.IsNullOrWhiteSpace(order.ReceiverMobile) == false)
                receiver.Add(new XElement("mobile", order.ReceiverMobile));
            string[] adds = order.ReceiverAddress.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            if (adds.Length < 3)
            {
                throw new Exception("地址格式不合法");
            }
            if (adds.Length == 3)
            {
                receiver.Add(new XElement("prov", adds[0]));
                receiver.Add(new XElement("city", adds[0] + "," + adds[1]));
                string add = "";
                for (int i = 2; i < adds.Length; i++)
                {
                    add += " " + adds[i];
                }
                receiver.Add(new XElement("address", add));
            }
            else
            {
                receiver.Add(new XElement("prov", adds[0]));
                receiver.Add(new XElement("city", adds[1] + "," + adds[2]));
                string add = "";
                for (int i = 3; i < adds.Length; i++)
                {
                    add += " " + adds[i];
                }
                receiver.Add(new XElement("address", add));
            }
            root.Add(receiver);
            root.Add(new XElement("agencyFund", order.PopPayType == OrderPopPayType.COD ? order.PopOrderMoney.ToString("F0") : "0.0"));
            root.Add(new XElement("itemsValue", order.PopPayType == OrderPopPayType.COD ? order.PopOrderMoney.ToString("F0") : "0.0"));
            root.Add(new XElement("itemsWeight", orderGoods.Select(obj => obj.Weight * obj.Count).Sum().ToString("F2")));

            var items = new XElement("items");
            items.Add(new XElement("item", new XElement("itemName", "女鞋"), new XElement("number", "1"), new XElement("itemValue", "1")));
            root.Add(items);

            XDocument xDoc = this.Post(isDebug ? YTOORDERURL_DEBUG : YTOORDERURL, root.ToString(SaveOptions.DisableFormatting));

            XElement retRoot = xDoc.Root;

            if (retRoot.Element("success").Value.Equals("true", StringComparison.OrdinalIgnoreCase) == false)
            {
                throw new Exception("请求圆通获取单号失败:" + retRoot.Element("reason").Value);
            }
            return retRoot.Element("orderMessage").Element("mailNo").Value.Trim();
        }

        public override void CancelOnline(WuliuNumber wuliuNumber)
        {
            var clientId = LocalConfigService.GetValue("YTOClientId", "");
            if (string.IsNullOrWhiteSpace(clientId))
            {
                throw new Exception("圆通电子面单账户为空，必须配置");
            }
            bool isDebug = LocalConfigService.GetValue("YTODebug", "false") == "false" ? false : true;

            XElement root = new XElement("UpdateInfo");
            root.Add(new XElement("logisticProviderID", "YTO"));
            root.Add(new XElement("clientID", clientId));
            root.Add(new XElement("mailNo", wuliuNumber.DeliveryNumber));
            root.Add(new XElement("txLogisticID", wuliuNumber.WuliuId));
            root.Add(new XElement("infoType", "INSTRUCTION"));
            root.Add(new XElement("infoContent", "WITHDRAW"));
            root.Add(new XElement("remark", "用户取消投递"));

            XDocument xDoc = this.Post(isDebug ? YTOORDERURL_DEBUG : YTOORDERURL, root.ToString());
            XElement retRoot = xDoc.Root;

            if (retRoot.Element("success").Value.Equals("true", StringComparison.OrdinalIgnoreCase) == false)
            {
                throw new Exception("请圆通取消订单失败:" + retRoot.Element("reason").Value);
            }
        }

        public override string GenenrateWuliuId(params string[] orderIds)
        {
            return this.GetClientId() + "_" + string.Join("_", orderIds);
        }
    }
}
